// Copyright 2015 Quuppa Oy. All rights reserved.
var Q = Q || {};
Q.TagDataRetriever = function(updateInterval) {
	this.__tagMap = {};
	this.__tagList = [];
	this.__query = window.location.search.substring(1);
	this.__listeners = [];
	this.__lastNotificationShownTS = 0;
	this.updateInterval = updateInterval;
	
	var that = this;	
	
	var v2 = true;
	if(this.__query != undefined && this.__query.indexOf("version=2") > -1) {
		v2 = true;
	}

	parseTagLocations = function(data, textStatus, jqXHR) {
		lastNotificationShownTS = 0;
		if(v2) {
			var serverTime = data.responseTS;
			data = data.tags;
		}
		var updatedTags = [];
		for (var i = 0; i < data.length; i++) {
			var tag = data[i];
			var localTag = that.__tagMap[tag.id];
			if (localTag === undefined)
				continue; // location info could arrive earlier than tagInfo... we need to ignore this until we have tagInfo data too. (causes too many problems elsewhere)
			localTag.last_location = localTag.location;// zc add
			localTag.location = tag;
			localTag.serverTime = serverTime;
			updatedTags.push(localTag);
		}
		
		// notify listeners
		for (var l = 0; l < that.__listeners.length; l++) {
				if (that.__listeners[l].onTagsUpdate != undefined)
					that.__listeners[l].onTagsUpdate(updatedTags);
		}
		
		for (var l = 0; l < that.__listeners.length; l++) {
			if (that.__listeners[l].onTagUpdateFinished != undefined)
				that.__listeners[l].onTagUpdateFinished();
		}

	};

	parseTagInfos = function(data, textStatus, jqXHR) {
		this.__lastNotificationShownTS = 0;
		if(v2) {
			var serverTime = data.responseTS;
			data = data.tags;
			var addedTags = [];
			var updatedTags = [];
			var error1_count = 0;
			var error2_count = 0;
			var e1_val = "";
			var e2_val = "";
			var mydate = new Date();
			if (typeof(data.length)=="undefined") {
				return;
			}
			for(var i = 0; i < data.length; i++) {
				var tag = data[i];
				var localTag = that.__tagMap[tag.id];
				var isAdd = true;

				var arr = tag.zones;
				var val = "";

				if(arr !== null && arr.length>0)
				{
					error1_count++;
					for(var j = 0; j < arr.length; j++) {
						val += 	" '" + arr[j].name + "' ";													
					}
					//e1_val = tag.id;
					e1_val += "<br>"+val+"区域的 '"+tag.name+"'";
				}
				if(tag.buttonState == "pushed")
				{
					error2_count++;		
					e2_val += "<br>默认区域的 '"+tag.name+"' 触发报警";		
				}				

				// if(i==(data.length-1))	// output
				// {
				// 	if(error1_count>0){
				// 		e1_val+="<br>总计 "+error1_count+" 个标签触发报警!";
				// 		Q.zoneAlarm.showNotification("⊙越界报警（"+mydate.toLocaleTimeString()+"）："+e1_val, 5000, error1_count);
				// 	}
				//
				// 	if(error2_count>0)
				// 		Q.keyAlarm.showNotification("⊙按键报警："+e2_val, 10000, error2_count);
				// }

				if (localTag === undefined) {
					localTag  = {};
					localTag.id = tag.id;
					//TODO: make a separate tag object?
					localTag.getPosition = function () {
						// decide should we use precise location or RSSI?
						var now = this.serverTime;
						var posAge = Number.MAX_VALUE;
						if(this.location && this.location.positionTS) {
							posAge = now-this.location.positionTS;
							if(posAge < Q.settings.maxAge || Q.settings.maxAge === 0) { 
								if (Q.settings.useSmoothing) {

								//zc add 
								if(this.last_location && Q.settings.optimize)
								{
									for(i=0;i<=2;i++)
									{
										if (typeof(this.location.smoothedPosition)!="undefined" &&　typeof(this.last_location.smoothedPosition)!="undefined") {
											this.location.smoothedPosition[i] = this.location.smoothedPosition[i] * Q.settings.nowFactor +
												this.last_location.smoothedPosition[i] * Q.settings.lastFactor;
											this.last_location.smoothedPosition[i] = this.location.smoothedPosition[i];
										}
									}

								}
								//zc add end
								
								if(this.location.smoothedPositionX !== undefined && this.location.smoothedPositionY !== undefined && this.location.smoothedPositionZ)
									return { 
										x: this.location.smoothedPositionX, 
										y: this.location.smoothedPositionY, 
										z: this.location.smoothedPositionZ, 
										type : "Smoothed",
										age: posAge,
										coordSystem: this.location.coordinateSystemId };  // v1.1 format
								else if (this.location.smoothedPosition !== undefined)  
									return { 
										x: this.location.smoothedPosition[0],
										y: this.location.smoothedPosition[1],
										z: this.location.smoothedPosition[2],
										type : "Smoothed",
										age: posAge,
										coordSystem: this.location.coordinateSystemId };  // v2 format
								}
								
								if (this.location.positionX !== undefined && this.location.positionY !== undefined && this.location.positionZ !== undefined)
									return { 
										x: this.location.positionX,
										y: this.location.positionY,
										z: this.location.positionZ,
										type: "Raw",
										age: posAge,
										coordSystem: this.location.coordinateSystemId };  // v1.1 format
								else if (this.location.position !== undefined)
									return { 
										x: this.location.position[0],
										y: this.location.position[1],
										z: this.location.position[2],
										type: "Raw",
										age: posAge,
										coordSystem: this.location.coordinateSystemId };  // v2 format
							}
						}						
						posAge = this.info.rssiTS !== undefined ? now-this.info.rssiTS : Number.MAX_VALUE;
						if(this.info.rssiLocatorCoords !== undefined && this.info.rssiLocatorCoords !== null)
							return { x: this.info.rssiLocatorCoords[0], y: this.info.rssiLocatorCoords[1], type: "RSSI", age: posAge, coordSystem: this.info.rssiCoordinateSystemId };
						return undefined;
					};

					localTag.getLastPosition = function () {
						// decide should we use precise location or RSSI?
						var now = this.serverTime;
						var posAge = Number.MAX_VALUE;
						if(this.last_location && this.last_location.positionTS) {
							posAge = now-this.last_location.positionTS;
							if(posAge < Q.settings.maxAge || Q.settings.maxAge === 0) { 
								if (Q.settings.useSmoothing) { 
									if(this.last_location.smoothedPositionX !== undefined && this.last_location.smoothedPositionY !== undefined && this.location.smoothedPositionZ)
										return { 
											x: this.last_location.smoothedPositionX, 
											y: this.last_location.smoothedPositionY, 
											z: this.last_location.smoothedPositionZ, 
											type : "Smoothed",
											age: posAge,
											coordSystem: this.last_location.coordinateSystemId };  // v1.1 format
									else if (this.last_location.smoothedPosition !== undefined)  
										return { 
											x: this.last_location.smoothedPosition[0],
											y: this.last_location.smoothedPosition[1],
											z: this.last_location.smoothedPosition[2],
											type : "Smoothed",
											age: posAge,
											coordSystem: this.last_location.coordinateSystemId };  // v2 format
								}
								
								if (this.last_location.positionX !== undefined && this.last_location.positionY !== undefined && this.last_location.positionZ !== undefined)
									return { 
										x: this.last_location.positionX,
										y: this.last_location.positionY,
										z: this.last_location.positionZ,
										type: "Raw",
										age: posAge,
										coordSystem: this.last_location.coordinateSystemId };  // v1.1 format
								else if (this.last_location.position !== undefined)
									return { 
										x: this.last_location.position[0],
										y: this.last_location.position[1],
										z: this.last_location.position[2],
										type: "Raw",
										age: posAge,
										coordSystem: this.last_location.coordinateSystemId };  // v2 format
							}
						}						
						posAge = this.info.rssiTS !== undefined ? now-this.info.rssiTS : Number.MAX_VALUE;
						if(this.info.rssiLocatorCoords !== undefined && this.info.rssiLocatorCoords !== null)
							return { x: this.info.rssiLocatorCoords[0], y: this.info.rssiLocatorCoords[1], type: "RSSI", age: posAge, coordSystem: this.info.rssiCoordinateSystemId };
						return undefined;
					};
					// create observer pattern for tag
					localTag.__observers = [];
					localTag.subscribe = function(fn) {
						localTag.__observers.push(fn);
					};
					localTag.unsubscribe = function(fn) {
						var i = localTag.__observers.indexOf(fn);
						if(i > -1) {
							localTag.__observers.splice(i, 1);
						}
					};
					localTag.fire = function(prop) {
				        this.__observers.forEach(function(item) {
				            item.call(localTag, prop);
				        });
				    }
					localTag.__visible = true;
					localTag.__autoFollow = false;
					
					that.__tagMap[tag.id] = localTag;
					that.__tagList.push(localTag);
					addedTags.push(localTag);
				} else {
					isAdd = false;
					updatedTags.push(localTag);
				}
				// copy values
				for (var key in tag) {
//					localTag[key] = tag[key];
				}
				localTag.info = tag;
				localTag.serverTime = serverTime;
			}
			// notify listeners
			for (var l = 0; l < that.__listeners.length; l++) {
				if (that.__listeners[l].onTagsAdd != undefined)
					that.__listeners[l].onTagsAdd(addedTags);
				if (that.__listeners[l].onTagsUpdate != undefined)
					that.__listeners[l].onTagsUpdate(updatedTags);
			}
		}
//		else {
//			for ( var key in data) {
//				if(key === "version" || key === "responseTimestampEpoch")
//					continue;
//					var tag = data[key];
//					tag.id = key;
//	
//					var existing = __tagMap[tag.id];
//					if (existing === undefined) {
//						newList[tag.id] = tag;
//						for (var l = 0; l < that.__listeners.length; l++) {
//							if (that.__listeners[l].onTagAdd != undefined)
//								that.__listeners[l].onTagAdd(tag);
//						}
//					} else {
//						//delete __tagMap[tag.id];
//						//newList[tag.id] = existing;
//	
//						for (var l = 0; l < that.__listeners.length; l++) {
//							if (that.__listeners[l].onTagUpdate != undefined)
//								that.__listeners[l].onTagUpdate(tag);
//						}
//					}
//					// hack to add button pressed to locations
////					if(__tagMap[tag.id] !== undefined) {
////						__tagMap[tag.id].buttonState = tag.buttonState;
////					}
//			}
//		}
//		
//		for(var id in __tagMap) {
//			if(!__tagMap.hasOwnProperty(id))
//				continue;
//			for (var l = 0; l < that.__listeners.length; l++) {
//				if (that.__listeners[l].onTagRemove != undefined)
//					that.__listeners[l].onTagRemove(__tagMap[id]);
//			}
//		}
//
//		__tagMap = newList;
	};

	// kick out the first requests
	setTimeout(this.__pollLocation, updateInterval, this);
	setTimeout(this.__pollTagInfo, updateInterval*10, this);
};


Q.TagDataRetriever.prototype.reset = function() {
	for (var l = 0; l < this.__listeners.length; l++) {
		if (this.__listeners[l].onTagsRemove != undefined)
			this.__listeners[l].onTagsRemove(__tagList);
	}
	this.__tagMap = {};
	this.__tagList = [];
};

Q.TagDataRetriever.prototype.sort = function() {
	this.__tagList.sort(function(a, b) {
		var idA = (a.info && a.info.name) || a.id;
		var idB = (b.info && b.info.name) || b.id;
		return idA.localeCompare(idB);
	});
	
	for (var l = 0; l < this.__listeners.length; l++) {
		if (this.__listeners[l].onTagsRemove != undefined)
			this.__listeners[l].onTagsRemove(this.__tagList);
		if (this.__listeners[l].onTagsAdd != undefined)
			this.__listeners[l].onTagsAdd(this.__tagList);
	}
};

Q.TagDataRetriever.prototype.addListener = function(l) {
	this.__listeners.push(l);
};

Q.TagDataRetriever.prototype.getTag = function(id) {
	return this.__tagMap[id];
};

Q.TagDataRetriever.prototype.getTags = function() {
	return this.__tagList;
};


Q.TagDataRetriever.prototype.__pollLocation = function(o) {
	// send poll for tag locations
	var maxAge = (Q.settings.maxAge > 0 ? "&maxAge=" + Math.floor(Q.settings.maxAge) : "");
	var radiusThreshold = (Q.settings.tagPositionRadiusThreshold > 0 ? "&radius=" + Q.settings.tagPositionRadiusThreshold : "");

	var q = o.__query;
	var that = this;
	// url="/getTagPosition?" + q + maxAge + radiusThreshold,
	jQuery.ajax({
		url : "/getTagPosition1",
		// url : "http://127.0.0.1:8080/qpe/getTagLocation",
		dataType : 'json',
		async : true,
		success : function(data, textStatus, jqXHR) {
			// parseTagLocations(data, textStatus, jqXHR);
			if(data!=null&&data!=""){
				parseTagInfos(data, "", "");
				parseTagLocations(data, "", "");
			}
			setTimeout(o.__pollLocation, o.updateInterval, o);
		},
		error : function(jqXHR, textStatus, errorThrown) {
			console.log('error', 'loading tag positions failed, ' + textStatus);
			if(new Date().getTime() - o.__lastNotificationShownTS > 20000) {
				Q.notificationManager.showNotification("Network error while retrieving tag locations.", 4000);
				o.__lastNotificationShownTS = new Date().getTime();
			}
			setTimeout(o.__pollLocation, o.updateInterval, o);
		}
	});
};
//
//
// Q.TagDataRetriever.prototype.__pollTagInfo = function(o) {
// 	var q = o.__query;
// 	var that = this;
// 	// do poll for tagInfos
// 	jQuery.ajax({
// 		url : "/getTagInfo?" + q,
// 		dataType : 'json',
// 		async : true,
// 		success : function(data, textStatus, jqXHR) {
// 			parseTagInfos(data, textStatus, jqXHR);
// 			setTimeout(o.__pollTagInfo, o.updateInterval*10, o);
// 		},
// 		error : function(jqXHR, textStatus, errorThrown) {
// 			console.log('error', 'loading tag info failed, ' + textStatus);
// 			if(new Date().getTime() - o.__lastNotificationShownTS > 20000) {
// 				Q.notificationManager.showNotification("Network error while retrieving tag infos.", 4000);
// 				o.__lastNotificationShownTS = new Date().getTime();
// 			}
// 			setTimeout(o.__pollTagInfo, o.updateInterval*10, o);
// 		}
// 	});
// };

// var socket;
// var address = window.globalConfig.address_map;
// if(typeof(WebSocket) == "undefined") {
// 	console.log("您的浏览器不支持WebSocket");
// }else{
// 	console.log("您的浏览器支持WebSocket");
// //实现化WebSocket对象，指定要连接的服务器地址与端口 建立连接
// //等同于socket = new WebSocket("ws://localhost:8083/checkcentersys/websocket/20");
// //socket = new WebSocket("http://localhost:8080/websocket/${cid}".replace("http","ws"));
// 	socket = new WebSocket("ws://10.35.76.222:8180/websocket");
// // 	socket = new WebSocket(address);
// //打开事件
// 	socket.onopen = function() {
// 		console.log("Socket 8180已打开");
// 		// $("#start").val("Socket 已打开")
// //socket.send("这是来自客户端的消息" + location.href + new Date());
// 	};
// //获得消息事件
// 	socket.onmessage = function(msg) {
// 		// console.log(msg.data);
// 		if (msg.data!="连接成功"){
// 			var data = JSON.parse(msg.data);
// 			parseTagInfos(data, "", "");
// 			parseTagLocations(data, "", "");
// 		}
// 	};
// //关闭事件
// 	socket.onclose = function() {
// 		console.log("Socket已关闭");
// 		// $("#close").val("Socket已关闭")
// 	};
// //发生了错误事件
// 	socket.onerror = function() {
// 		alert("Socket发生了错误");
// //此时可以尝试刷新页面
// 	}

// }
